@file:JvmName("ActivityExtensions")

package com.example.mytestdemo.extensions

import android.app.Activity
import android.content.Intent
import android.os.Build
import android.os.CountDownTimer
import android.os.Handler
import android.view.View
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

fun AppCompatActivity.doOnLifecycleEvent(doOnLifecycleEvent: () -> Unit, vararg targetEvents: Lifecycle.Event) {
    lifecycle.addObserver(object : LifecycleEventObserver {
        override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
            if (targetEvents.contains(Lifecycle.Event.ON_ANY)) {
                doOnLifecycleEvent()
                return
            }
            if (targetEvents.contains(event)) {
                doOnLifecycleEvent()
            }
        }
    })
}

fun AppCompatActivity.doOnceOnLifecycleEvent(doOnceOnLifecycleEvent: () -> Unit, vararg targetEvents: Lifecycle.Event) {
    val viewModel = ViewModelProvider(this)[ActivityExtensionsViewModel::class.java]
    lifecycle.addObserver(object : LifecycleEventObserver {
        override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
            if (targetEvents.contains(Lifecycle.Event.ON_ANY)) {
                if (!viewModel.terminated) {
                    doOnceOnLifecycleEvent()
                    viewModel.terminated = true
                }
                return
            }
            if (targetEvents.contains(event)) {
                if (!viewModel.terminated) {
                    doOnceOnLifecycleEvent()
                    viewModel.terminated = true
                }
            }
        }
    })
}


fun AppCompatActivity.safePostDelayed(delay: Long, runnable: () -> Unit) {
    safePostDelayed(delay, Lifecycle.Event.ON_DESTROY, runnable)
}

fun AppCompatActivity.safePostDelayed(delay: Long, stopOnEvent: Lifecycle.Event, runnable: () -> Unit) {
    val handler = Handler()
    val run = Runnable { runnable() }
    handler.postDelayed(run, delay)
    lifecycle.addObserver(object : LifecycleEventObserver {
        override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
            if (stopOnEvent == event) {
                handler.removeCallbacks(run)
            }
        }
    })
}


fun Activity.safeIntervalTask(times: Int = 0, delay: Long = 0L, period: Long, runnable: () -> Unit) = findViewById<View>(android.R.id.content)?.safeIntervalTask(times, delay, period, runnable)

fun Activity.safeCountDownTask(millsInFuture: Long, countDownInterval: Long, onTick: ((timer: CountDownTimer, millisUntilFinished: Long) -> Unit)? = null, onFinish: (() -> Unit)? = null, onCancel: (() -> Unit)? = null) = findViewById<View>(android.R.id.content)?.safeCountDownTask(millsInFuture, countDownInterval, onTick, onFinish, onCancel)

/**
 * 让布局不要延伸到刘海危险区域
 * 先适配P及以上吧!
 */
fun AppCompatActivity.cutOutModeNeverInP() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        val lp = window.attributes
        lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
        window.attributes = lp
    }
}


suspend fun AppCompatActivity.startActivityForResultSuspend(intent: Intent, requestCode: Int = 100): ActivityResult {
    return suspendCoroutine {
        val fragment = ForResultFragment()
        fragment.setCallback(object : ForResultFragment.Callback() {
            override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
                super.onActivityResult(requestCode, resultCode, data)
                it.resume(ActivityResult(requestCode, resultCode, data))
            }
        })
        supportFragmentManager.beginTransaction()
            .add(fragment, "ForResultFragment")
            .commitNowAllowingStateLoss()
        fragment.startActivityForResult(intent, requestCode)
    }
}

suspend fun FragmentActivity.startActivityForResultSuspend(intent: Intent, requestCode: Int = 100): ActivityResult {
    return suspendCoroutine {
        val fragment = ForResultFragment()
        fragment.setCallback(object : ForResultFragment.Callback() {
            override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
                super.onActivityResult(requestCode, resultCode, data)
                it.resume(ActivityResult(requestCode, resultCode, data))
            }
        })
        supportFragmentManager.beginTransaction()
            .add(fragment, "ForResultFragment")
            .commitNowAllowingStateLoss()
        fragment.startActivityForResult(intent, requestCode)
    }
}

fun AppCompatActivity.startActivityForResultCallback(intent: Intent, requestCode: Int, callback: (result: ActivityResult) -> Unit) {
    GlobalScope.launch(Dispatchers.Main) {
        val result = startActivityForResultSuspend(intent, requestCode)
        callback.invoke(result)
    }
}

fun AppCompatActivity.startActivityForResultCallback(intent: Intent, callback: (result: ActivityResult) -> Unit) {
    GlobalScope.launch(Dispatchers.Main) {
        val result = startActivityForResultSuspend(intent, 100)
        callback.invoke(result)
    }
}

//@Deprecated("统一用AndPermission库，方便合规整规")
//suspend fun AppCompatActivity.requestPermissionsSuspend(permissions: Array<String>, requestCode: Int = 100): PermissionResult {
//    return suspendCoroutine {
//        val fragment = ForResultFragment()
//        fragment.setCallback(object : ForResultFragment.Callback() {
//            override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
//                super.onRequestPermissionsResult(requestCode, permissions, grantResults)
//                it.resume(PermissionResult(requestCode, permissions, grantResults))
//            }
//        })
//        supportFragmentManager.beginTransaction()
//            .add(fragment, "PermissionResultFragment")
//            .commitNowAllowingStateLoss()
//        fragment.requestPermissions(permissions, requestCode)
//    }
//}

//@Deprecated("统一用AndPermission库，方便合规整规")
//fun AppCompatActivity.requestPermissionsCallback(permissions: Array<String>, requestCode: Int, callback: (result: PermissionResult) -> Unit) {
//    GlobalScope.launch(Dispatchers.Main) {
//        val result = requestPermissionsSuspend(permissions, requestCode)
//        callback.invoke(result)
//    }
//}

//@Deprecated("统一用AndPermission库，方便合规整规")
//fun AppCompatActivity.requestPermissionsCallback(permissions: Array<String>, callback: (result: PermissionResult) -> Unit) {
//    GlobalScope.launch(Dispatchers.Main) {
//        val result = requestPermissionsSuspend(permissions, 100)
//        callback.invoke(result)
//    }
//}